package com.gzhryc.pay.adaptation.weixin;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用于RPC，将无法序列化的HTTP连接保存在这里
 */
public class WXHttpClient implements Serializable {

    private static ConcurrentHashMap<String, HTTPClientEntity> httpClientMap = new ConcurrentHashMap<>();

    public static CloseableHttpClient getHttpClient(String appId,P12File p12File)
            throws KeyStoreException, KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException, IOException {
        HTTPClientEntity entity = httpClientMap.get(appId);
        if(entity != null && p12File != null){
            if(entity.getP12File() == null){
                entity = null;
            }
        }

        if (entity == null) {
            if (p12File != null) {
                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                if (p12File.getFile() != null) {
                    FileInputStream instream = new FileInputStream(p12File.getFile());
                    try {
                        keyStore.load(instream, p12File.getPassword().toCharArray());
                    } finally {
                        instream.close();
                    }
                } else if (p12File.getData() != null && p12File.getData().length > 0) {
                    InputStream instream = new ByteArrayInputStream(p12File.getData());
                    try {
                        keyStore.load(instream, p12File.getPassword().toCharArray());
                    } finally {
                        instream.close();
                    }
                }

                SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, p12File.getPassword().toCharArray()).build();
                //TODO openJDK11版本不支持TLSv1协议
                //SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
                //		SSLConnectionSocketFactory.getDefaultHostnameVerifier());

                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, null, null,
                        SSLConnectionSocketFactory.getDefaultHostnameVerifier());

                CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
                entity = new HTTPClientEntity(httpClient,p12File);
            } else {
                CloseableHttpClient httpClient = HttpClients.custom().build();
                entity = new HTTPClientEntity(httpClient);
            }
            //缓存HTTP客户端
            httpClientMap.put(appId,entity);
        }
        return entity.client;
    }

    public static class HTTPClientEntity {

        CloseableHttpClient client;
        P12File p12File;

        public HTTPClientEntity(){}

        public HTTPClientEntity(CloseableHttpClient client){
            this.client = client;
        }

        public HTTPClientEntity(CloseableHttpClient client,P12File p12File){
            this.client = client;
            this.p12File = p12File;
        }

        public CloseableHttpClient getClient() {
            return client;
        }

        public void setClient(CloseableHttpClient client) {
            this.client = client;
        }

        public P12File getP12File() {
            return p12File;
        }

        public void setP12File(P12File p12File) {
            this.p12File = p12File;
        }
    }
}
